package com.taichuan.selfcheck.ui.fragment;

import android.annotation.SuppressLint;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Bundle;
import android.telephony.PhoneStateListener;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.taichuan.selfcheck.R;
import com.taichuan.selfcheck.config.PropertyDefaultValue;
import com.taichuan.selfcheck.mvp.presenter.EmptyPresenter;
import com.taichuan.selfcheck.mvp.viewinterface.EmptyInterface;
import com.taichuan.selfcheck.ui.dialog.ResultDialog;
import com.taichuan.selfcheck.ui.fragment.base.AppBaseFragment;

import org.greenrobot.eventbus.EventBus;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Set;

import butterknife.BindView;
import butterknife.OnClick;

/**
 * 移动网络测试
 *
 * @author lqd
 */
public class MobileNetworkTestFragment extends AppBaseFragment<EmptyInterface, EmptyPresenter> implements EmptyInterface {

    private static final String TAG = "MobileNetworkTest";

    ResultDialog resultDialog;

    @BindView(R.id.mobileNetworkInfoTv)
    TextView mobileNetworkInfoTv;
    @BindView(R.id.mobileSignalStrengthsInfoTv)
    TextView mobileSignalStrengthsInfoTv;
    @BindView(R.id.apnListRv)
    RecyclerView apnListRv;

    @BindView(R.id.createMobileApnBtn)
    Button createMobileApnBtn;
    @BindView(R.id.createUnionApnBtn)
    Button createUnionApnBtn;
    @BindView(R.id.deleteApnBtn)
    Button deleteApnBtn;

    @Override
    protected int setContentViewId() {
        return R.layout.fragment_mobile_network_test;
    }

    @SuppressWarnings("StringBufferReplaceableByString")
    @SuppressLint("SetTextI18n")
    @Override
    protected void initView(View view, Bundle bundle) {
        Context context = Objects.requireNonNull(getContext());
        //设置弹窗发送的事件——移动网络测试
        resultDialog = new ResultDialog(PropertyDefaultValue.FUNCTION_TEST_18, getResources().getString(R.string.mobile_network_test), context);
        // 列表
        apnListRv.setLayoutManager(new LinearLayoutManager(getContext()));
        apnAdapter = new ApnAdapter(apnBeans);
        apnListRv.setAdapter(apnAdapter);
        queryApns();
        // 读取移动网络信息
        readMobileNetworkInfo();
        if (hasSimCard(context)) {
            // 设置网络强度监听
            TelephonyManager mTelephonyManager = (TelephonyManager) Objects.requireNonNull(getContext()).getSystemService(Context.TELEPHONY_SERVICE);
            if (mTelephonyManager != null) {
                mTelephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
            }
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        // 取消注册信号监听
        TelephonyManager mTelephonyManager = (TelephonyManager) Objects.requireNonNull(getContext()).getSystemService(Context.TELEPHONY_SERVICE);
        if (mTelephonyManager != null) {
            mTelephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE);
        }
    }

    @Override
    protected boolean isAllowAutoFinishFragment() {
        return false;
    }

    @Override
    public void doOnAutoFinishFragment() {
        resultDialog.show();
    }

    @Override
    protected void getBundleValues(Bundle bundle) {

    }

    @Override
    protected EmptyPresenter createPresenter() {
        return new EmptyPresenter();
    }

    @OnClick({
            R.id.createMobileApnBtn,
            R.id.createUnionApnBtn,
            R.id.deleteApnBtn
    })
    @Override
    protected void onXmlClick(View v) {
        super.onXmlClick(v);
        final int id = v.getId();
        if (id == R.id.createMobileApnBtn) {
            createApn("移动IOT", "cmiot");
        } else if (id == R.id.createUnionApnBtn) {
            createApn("联通IOT", "unim2m.njm2mapn");
        } else if (id == R.id.deleteApnBtn) {
            for (String d : apnAdapter.selectIds) {
                deleteApns(d);
            }
        }
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if (resultDialog.isShowing()) {
            resultDialog.dispatchKeyEvent(event);
        }
        if (event.getKeyCode() == KeyEvent.KEYCODE_1) {
            createMobileApnBtn.performClick();
        } else if (event.getKeyCode() == KeyEvent.KEYCODE_2) {
            createUnionApnBtn.performClick();
        } else if (event.getKeyCode() == KeyEvent.KEYCODE_3) {
            deleteApnBtn.performClick();
        }
        return super.dispatchKeyEvent(event);
    }

    //******************************** apn列表 ********************************//

    private final List<ApnBean> apnBeans = new ArrayList<>();
    private ApnAdapter apnAdapter;

    private static final class ApnBean {
        public final String id;
        public final String name;
        public final String apn;

        public ApnBean(String name, String apn) {
            this.id = null;
            this.name = name;
            this.apn = apn;
        }

        public ApnBean(String id, String name, String apn) {
            this.id = id;
            this.name = name;
            this.apn = apn;
        }

        @Override
        public String toString() {
            return "ApnBean{" +
                    "id='" + id + '\'' +
                    ", name='" + name + '\'' +
                    ", apn='" + apn + '\'' +
                    '}';
        }
    }

    private static final class ApnViewHolder extends RecyclerView.ViewHolder {

        public final TextView apnNameTv;
        public final CheckBox apnCheckBox;

        public ApnViewHolder(@NonNull View itemView) {
            super(itemView);
            apnNameTv = itemView.findViewById(R.id.apnNameTv);
            apnCheckBox = itemView.findViewById(R.id.apnCheckBox);
        }
    }

    private static final class ApnAdapter extends RecyclerView.Adapter<ApnViewHolder> {

        private final List<ApnBean> apnBeans;
        public final Set<String> selectIds = new HashSet<>();

        public ApnAdapter(List<ApnBean> apnBeans) {
            this.apnBeans = apnBeans;
        }

        @Override
        public int getItemCount() {
            return apnBeans.size();
        }

        @NonNull
        @Override
        public ApnViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_mobile_network_apn, parent, false);
            return new ApnViewHolder(itemView);
        }

        @SuppressLint("SetTextI18n")
        @Override
        public void onBindViewHolder(@NonNull ApnViewHolder holder, int position) {
            ApnBean bean = apnBeans.get(position);
            holder.apnNameTv.setText(bean.id + ": " + bean.name + ", " + bean.apn);
            holder.apnCheckBox.setOnCheckedChangeListener(null);
            holder.apnCheckBox.setChecked(selectIds.contains(bean.id));
            holder.apnCheckBox.setOnCheckedChangeListener((buttonView, isChecked) -> {
                if (isChecked) {
                    selectIds.add(bean.id);
                } else {
                    selectIds.remove(bean.id);
                }
            });
        }

    }

    //******************************** 网络 ********************************//

    private static final String NETWORKTYPE_NONE = "没有网络";
    private static final String NETWORKTYPE_WIFI = "WIFI";
    private static final String NETWORKTYPE_ETHERNET = "以太网";
    private static final String NETWORKTYPE_2G = "2G";
    private static final String NETWORKTYPE_4G = "4G";

    /**
     * 判断是否包含SIM卡
     *
     * @return 状态
     */
    public static boolean hasSimCard(Context context) {
        TelephonyManager telMgr = (TelephonyManager)
                context.getSystemService(Context.TELEPHONY_SERVICE);
        int simState = telMgr.getSimState();
        boolean result = true;
        switch (simState) {
            case TelephonyManager.SIM_STATE_ABSENT:
            case TelephonyManager.SIM_STATE_UNKNOWN:
                result = false; // 没有SIM卡
                break;
        }
        return result;
    }

    public static String getNetWorkType(Context context) {
        ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = manager.getActiveNetworkInfo();
        if (networkInfo != null && networkInfo.isConnected()) {
            String type = networkInfo.getTypeName();
            Log.d(TAG, "getNetWorkType: type=" + type);
            if (type.equalsIgnoreCase("WIFI")) {
                return NETWORKTYPE_WIFI;
            } else if (type.equalsIgnoreCase("ETHERNET")) {
                return NETWORKTYPE_ETHERNET;
            } else if (type.equalsIgnoreCase("MOBILE")) {
                return isFastMobileNetwork(context) ? NETWORKTYPE_4G : NETWORKTYPE_2G;
            }
        }
        return NETWORKTYPE_NONE;
    }

    /**
     * 判断网络类型
     */
    private static boolean isFastMobileNetwork(Context context) {
        TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        return telephonyManager.getNetworkType() == TelephonyManager.NETWORK_TYPE_LTE;
    }

    private static String getSIMInfo(Context context) {
        TelephonyManager iPhoneManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        return iPhoneManager.getSimOperator();
    }

    private final PhoneStateListener phoneStateListener = new PhoneStateListener() {
        @SuppressLint("SetTextI18n")
        @Override
        public void onSignalStrengthsChanged(SignalStrength signalStrength) {
            super.onSignalStrengthsChanged(signalStrength);
            int asu = signalStrength.getGsmSignalStrength();
            mobileSignalStrengthsInfoTv.setText("移动网络强度：" + asu);
        }
    };

    public static final Uri APN_CREATE_URI = Uri.parse("content://telephony/carriers");
    public static final Uri APN_URI = Uri.parse("content://telephony/carriers/current");

    public void queryApns() {
        apnBeans.clear();
        try (Cursor cr = Objects.requireNonNull(getContext()).getContentResolver().query(APN_URI, null, null, null, null)) {
            while (cr != null && cr.moveToNext()) {
                String id = cr.getString(cr.getColumnIndex("_id"));
                String name = cr.getString(cr.getColumnIndex("name"));
                String apn = cr.getString(cr.getColumnIndex("apn"));
                String type = cr.getString(cr.getColumnIndex("type"));
                String numeric = cr.getString(cr.getColumnIndex("numeric"));
                ApnBean bean = new ApnBean(id, name, apn);
                apnBeans.add(bean);
                Log.d(TAG, "queryApns: bean=" + bean + ", type=" + type + ", numeric=" + numeric);
            }
            apnAdapter.notifyDataSetChanged();
        }
    }

    public void deleteApns(String id) {
        ContentResolver contentResolver = Objects.requireNonNull(getContext()).getContentResolver();
        contentResolver.delete(APN_URI, "_id=?", new String[]{id});
        Iterator<ApnBean> iterator = apnBeans.iterator();
        while (iterator.hasNext()) {
            ApnBean bean = iterator.next();
            if (id.equals(bean.id)) {
                iterator.remove();
            }
        }
        apnAdapter.notifyDataSetChanged();
        // 延时更新网络状态
        apnListRv.postDelayed(this::readMobileNetworkInfo, 2000);
    }

    public void createApn(String name, String apn) {
        Context context = Objects.requireNonNull(getContext());
        if (!hasSimCard(context)) {
            Toast.makeText(getContext(), "没有Sim卡", Toast.LENGTH_SHORT).show();
            return;
        }
        for (ApnBean apnBean : apnBeans) {
            if (name.equals(apnBean.name) && apn.equals(apnBean.apn)) {
                Toast.makeText(getContext(), "已存在相同的APN", Toast.LENGTH_SHORT).show();
                return;
            }
        }
        String numeric = getSIMInfo(context);
        Log.d(TAG, "createApn: numeric=" + numeric);
        if (TextUtils.isEmpty(numeric)) {
            Toast.makeText(getContext(), "创建APN失败，numeric为空", Toast.LENGTH_SHORT).show();
            return;
        }
        ContentValues contentValues = new ContentValues();
        contentValues.put("name", name);
        contentValues.put("apn", apn);
        contentValues.put("type", "");
        contentValues.put("numeric", numeric);
        contentValues.put("mcc", numeric.substring(0, 3));
        contentValues.put("mnc", numeric.substring(3));
        contentValues.put("proxy", "");
        contentValues.put("port", "");
        contentValues.put("mmsproxy", "");
        contentValues.put("mmsport", "");
        contentValues.put("user", "");
        contentValues.put("server", "");
        contentValues.put("password", "");
        contentValues.put("mmsc", "");
        ContentResolver contentResolver = Objects.requireNonNull(getContext()).getContentResolver();
        Uri insertedUri = contentResolver.insert(APN_CREATE_URI, contentValues);
        Log.d(TAG, "createApn: insertedUri=" + insertedUri);
        queryApns();
        // 延时更新网络状态
        apnListRv.postDelayed(this::readMobileNetworkInfo, 2000);
    }

    private void readMobileNetworkInfo() {
        Context context = getContext();
        if (context == null) {
            return;
        }
        StringBuilder networkInfo = new StringBuilder();
        boolean hasSim = hasSimCard(context);
        networkInfo.append("是否有Sim卡：").append(hasSim).append('\n');
        networkInfo.append("网络类型：").append(getNetWorkType(context)).append('\n');
        mobileNetworkInfoTv.setText(networkInfo.toString());
    }

}
